﻿using Hx.ADSyncPlatform.ActiveDirectory;
using Hx.ADSyncPlatform.ActiveDirectory.Extension;
using Hx.ADSyncPlatform.ActiveDirectory.Model;
using Hx.ADSyncPlatform.Controllers.Base;
using Hx.ADSyncPlatform.Entity.Entities;
using Hx.ADSyncPlatform.Infrastructure.Cache;
using Hx.ADSyncPlatform.Service;
using Hx.ADSyncPlatform.WebApi.Model;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Hx.ADSyncPlatform.Controllers
{
    /// <summary>
    /// 数据权限
    /// </summary>
    [Route("api/plat/dataPermission")]
    [Authorize]
    [ApiController]
    public class Plat_DataPermissionController : BaseController
    {
        private Plat_DataPermissionService plat_DataPermissionService;
        private ActiveDirectoryClient activeDirectoryClient;
        private SystemConfig systemConfig;
        private ICacheService cacheService;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="plat_DataPermissionService"></param>
        /// <param name="cacheService"></param>
        /// <param name="myOptionsAccessor"></param>
        /// <param name="activeDirectoryClient"></param>
        /// <param name="serviceProvider"></param>
        public Plat_DataPermissionController(Plat_DataPermissionService plat_DataPermissionService, ICacheService cacheService, IOptions<SystemConfig> myOptionsAccessor, ActiveDirectoryClient activeDirectoryClient, IServiceProvider serviceProvider) : base(serviceProvider)
        {
            this.plat_DataPermissionService = plat_DataPermissionService;
            this.activeDirectoryClient = activeDirectoryClient;
            this.systemConfig = myOptionsAccessor.Value;
            this.cacheService = cacheService;


        }

        #region 数据权限管理


        /// <summary>
        /// 数据权限treeselect数据源
        /// </summary>
        /// <param name="objectGuid">管理员objectguid</param>
        /// <returns></returns>
        ////[Authorize(policy: "privilege")]
        [HttpGet("menuTree")]
        public async Task<Result<Dictionary<string, IList>>> GetMenuTree(Guid objectGuid)
        {
            Organization organization = activeDirectoryClient.Organizations.Root();
            OuTreeModel treeModel = organization.ConvertToTree();
            List<string> excludeCnList = systemConfig.systemOU.Select(n => n.cn).ToList();
            List<Organization> organizations = activeDirectoryClient.Organizations.GetByDN(organization.DistinguishedName, SearchScopeDerivation.OneLevel, excludeCnList);
            List<OuTreeModel> subList = organizations.ConvertToTree();
            subList.ForEach(n =>
            {
                n.ParentId = organization.DistinguishedName;
                n.isLeaf = !activeDirectoryClient.Organizations.HasChildren(n.data.DistinguishedName, excludeCnList, null, false);
            });
            treeModel.children = subList;

            var data = new List<OuTreeModel>() { treeModel };
            var expandedKeys = new List<string>() { treeModel.id };
            Dictionary<string, IList> result = new Dictionary<string, IList>();
            result.Add("all", data);

            var ownedList = await plat_DataPermissionService.GetDataPersmissionsByObjectGuid(objectGuid);
            var ownedIds = ownedList.Select(n => n.Dn).ToList();
            result.Add("checkedKeys", ownedIds);
            result.Add("expandedKeys", expandedKeys);

            return await base.Success<Dictionary<string, IList>>(result);
        }

        /// <summary>
        /// treeselect 懒加载
        /// </summary>
        /// <param name="dn"></param>
        /// <param name="objectGuid"></param>
        /// <returns></returns>
        [HttpGet("sublist")]
        public async Task<Result<Dictionary<string, IList>>> SubList(string dn, Guid objectGuid)
        {
            List<string> excludeCnList = systemConfig.systemOU.Select(n => n.cn).ToList();
            List<Organization> organizations = activeDirectoryClient.Organizations.GetByDN(dn, SearchScopeDerivation.OneLevel, excludeCnList);

            List<OuTreeModel> subList = organizations.ConvertToTree();
            subList.ForEach(n =>
            {
                n.ParentId = dn;
                n.isLeaf = !activeDirectoryClient.Organizations.HasChildren(n.data.DistinguishedName, excludeCnList, null, false);
            });

            Dictionary<string, IList> result = new Dictionary<string, IList>();
            result.Add("all", subList);
            var ownedList = await plat_DataPermissionService.GetDataPersmissionsByObjectGuid(objectGuid);
            var ownedIds = ownedList.Select(n => n.Dn).ToList();
            result.Add("checkedKeys", ownedIds);
            return await base.Success<Dictionary<string, IList>>(result);

        }

        /// <summary>
        /// 给平台管理员分配数据权限
        /// </summary>
        /// <param name="objectGuid">管理员objectGuid</param>
        /// <param name="plat_DataPermissions">数据权限集合</param>
        /// <returns></returns>
        //[Authorize(policy: "privilege")]
        [HttpPost("{objectGuid}/assign")]
        public async Task<Result> AssignDataPermissions([FromRoute] Guid objectGuid, [FromBody] List<Plat_DataPermission> plat_DataPermissions)
        {
            this.plat_DataPermissionService.AssignDataPermission(objectGuid, plat_DataPermissions);
            await this.InitDataPermissions(objectGuid);//刷新缓存权限
            return await base.Success();
        }

        private async Task InitDataPermissions(Guid objectGuid)
        {
            string cacheKey = string.Format(dataPermissionCacheKey, objectGuid.ToString());
            List<Plat_DataPermission> dataPermissions = await this.plat_DataPermissionService.GetDataPersmissionsByObjectGuid(objectGuid);
            this.cacheService.Remove(cacheKey);
            //this.cacheService.Add(cacheKey, dataPermissions, (int)requirement.RefreshTokenExpire.TotalMinutes);
            this.cacheService.Add(cacheKey, dataPermissions);//永不过期
        }




        #endregion

    }
}
